package com.virgo.login.service;

import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.virgo.common.entity.IUserToken;
import com.virgo.common.exception.INoLoginException;
import com.virgo.common.utils.ITimeUtils;
import com.virgo.login.config.LoginConfig;
import com.virgo.redis.service.RedisService;
import com.virgo.web.utils.IRequestUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;

@Component
public class TokenService {

	@Autowired
	private RedisService redisService;

	@Autowired
	private LoginConfig loginConfig;

	/**
	 * 生成token
	 * @param data 用户信息
	 * @return HashMap<String,Object>
	 */
	public HashMap<String,Object> createToken(IUserToken data) {
		String tokenKey = "token_" + data.getUserType() + "_" + data.getUserId();
		String token = redisService.get(tokenKey);

		if (!loginConfig.getConcurrent() && !ObjectUtils.isEmpty(token)) {
			redisService.del(tokenKey);
			redisService.del(token);
		}

		token = DigestUtil.md5Hex(tokenKey + ITimeUtils.localDate());
		String tokenData = JSON.toJSONString(data);
		redisService.set(tokenKey,token,loginConfig.getTimeout());
		redisService.set(token,tokenData,loginConfig.getTimeout());

		HashMap<String,Object> result = new HashMap<>(1);
		result.put("token",token);
		return result;
	}
	/**
	 * 获取当前登录用户信息
	 * @return UserToken
	 */
	public IUserToken get(boolean throwException) {
		return get("token",throwException);
	}

	/**
	 * 获取header的用户信息
	 * @param headerKey String
	 * @param throwException boolean
	 * @return UserToken
	 */
	public IUserToken get(String headerKey, boolean throwException) {
		HttpServletRequest request = IRequestUtils.getHttpServletRequest();
		String token = request.getHeader(headerKey);
		if (ObjectUtils.isEmpty(token)) {
			if (throwException) {
				throw new INoLoginException("请登录");
			}
			return null;
		}
		String tokenResult = redisService.get(token);
		if (ObjectUtils.isEmpty(tokenResult)) {
			if (throwException) {
				throw new INoLoginException("请登录");
			}
			return null;
		}
		IUserToken userToken = jsonToJavaObject(tokenResult);
		if (loginConfig.getCheckDeviceUserType().equals(userToken.getUserType()) && !loginConfig.getConcurrent() ) {
			String ip = IRequestUtils.getIpAddr(request);
			String userAgent = request.getHeader("User-Agent");
			String unique = DigestUtil.md5Hex(ip + "_" + userAgent);
			if (!userToken.getUnique().equals(unique)) {
				if (throwException) {
					throw new INoLoginException("请登录");
				}
				return null;
			}
		}
		redisService.expire(token,loginConfig.getTimeout());
		String tokenKey = "token_" + userToken.getUserType() + "_" + userToken.getUserId();
		redisService.expire(tokenKey,loginConfig.getTimeout());
		return userToken;
	}

	/**
	 * 退出登录
	 */
	public void logout(String headerKey) {
		String token = IRequestUtils.getHttpServletRequest().getHeader(headerKey);
		if (!ObjectUtils.isEmpty(token)) {
			String tokenResult = redisService.get(token);
			if (!ObjectUtils.isEmpty(tokenResult)) {
				IUserToken userToken = jsonToJavaObject(tokenResult);
				String tokenKey = "token_" + userToken.getUserType() + "_" + userToken.getUserId();
				redisService.del(tokenKey);
			}
			redisService.del(token);
		}
	}

	public void logout() {
		logout("token");
	}

	/**
	 * 强制某人下线
	 * @param userType String
	 * @param userId String
	 */
	public void delete(String userType, Long userId) {
		String tokenKey = "token_" + userType + "_" + userId;
		String token = redisService.get(tokenKey);
		if (!ObjectUtils.isEmpty(token)) {
			redisService.del(token);
		}
		redisService.del(tokenKey);
	}

	private IUserToken jsonToJavaObject(String tokenResult) {
		JSONObject tokenData = JSON.parseObject(tokenResult);
		return tokenData.toJavaObject(IUserToken.class);
	}
}
